const addon = require('../../build/Release/addon')
function Player() {
  if (this.__proto__.constructor !== Player) {
    return new Player()
  }
  this.player = addon.Player()
  this.prepared = false
  this.url = ''
  Object.defineProperty(this, 'state', {
    get() {
      return this.player.state
    }
  })
  Object.defineProperty(this, 'duration', {
    get() {
      return this.player.duration
    }
  })
  Object.defineProperty(this, 'currentPos', {
    get() {
      return this.player.currentPos
    }
  })
  Object.defineProperty(this, 'volume', {
    get() {
      return this.player.volume
    },
    set(value) {
      if (value < 0) value = 0
      else if (value > 128) value = 128
      this.player.volume = Math.floor(value)
    }
  })
}

Player.prototype.prepare = function (url) {
  return new Promise((resolve, reject) => {
    this.url = url
    this.player.prepare(url, err => {
      if (err) {
        reject(err)
        this.prepared = false
      } else {
        resolve(this)
        this.prepared = true
      }
    })
  })
}

Player.prototype.play = function (onFrame) {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  return new Promise((resolve, reject) => {
    const cb = onFrame || (() => { })
    this.player.play(cb, () => {
      resolve()
    })
  })
}

Player.prototype.pause = function () {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  this.player.pause()

}

Player.prototype.resume = function () {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  this.player.resume()

}

Player.prototype.stop = function () {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  this.player.stop()

}

Player.prototype.setTempo = function (tempo) {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  if (tempo < 0.01) {
    tempo = 0.01
    console.warn('tempo too low, set to 0.01 forcely')
  }
  else if (tempo > 10) {
    tempo = 10
    console.warn('tempo too high, set to 10 forcely')
  }
  this.player.setTempo(tempo)

}

Player.prototype.setPitch = function (pitch) {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  if (pitch < -18) {
    pitch = -18
    console.warn('pitch too low, set to -18 forcely')
  }
  else if (pitch > 18) {
    pitch = 18
    console.warn('pitch too high, set to 18 forcely')
  }
  this.player.setPitch(pitch)

}

Player.prototype.seek = function (time) {
  if (!this.prepared)
    throw new Error("please call prepare() first")
  return new Promise((resolve, reject) => {
    this.player.seek(time, err => {
      if (err) {
        reject(err)
      }
      resolve()
    })
  })

}

module.exports = Player